package yf.mall.service.impl;

import com.yf.response.RRException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.transaction.annotation.Transactional;
import yf.mall.common.Const;
import yf.mall.dao.*;
import yf.mall.entity.*;
import yf.mall.enums.*;
import yf.mall.service.AccountService;
import yf.mall.service.MallActService;
import com.yf.service.impl.BaseServiceImpl;
import yf.mall.vo.ItemVo;
import yf.mall.vo.TicketVo;

/**
 * 活动Service实现类
 *
 * @author hxf
 * @email 505860922@qq.com
 * @date Mon Nov 25 13:53:21 CST 2019
 */
@Service
public class MallActServiceImpl extends BaseServiceImpl<MallActEntity> implements MallActService {

    private MallActDao mallActDao;

    @Autowired
    private AccountService accountService;

    @Autowired
    private UserDao userDao;

    @Autowired
    private OrderItemDao itemDao;

    @Autowired
    private AreaDao areaDao;

    @Autowired
    private LevelDao levelDao;

    @Autowired
    private MallCardDao mallCardDao;

    @Autowired
    private MallGoodsDao mallGoodsDao;


    @Autowired
    public void setDao(MallActDao mallActDao) {
        this.mallActDao = mallActDao;
        super.setBaseDao(mallActDao);
    }


    /**
     *
     *   @Override
     *     public List<UserVo> queryListVo(UserVo userVo) {
     *         return userDao.queryListVo(userVo);
     *     }
     *
     *     @Override
     *     public UserVo getVo(Long id) {
     *         return userDao.getVo(id);
     *     }

     @Override List<MallActVo> queryListVo(MallActVo mallActVo){
     return mallActDao.queryListVo(mallActVo);
     }

     @Override MallActVo getVo(Long id){
     return mallActDao.getVo(id);
     }
     **/


    /**内部方法**/

    /**
     * 分享奖励
     *
     * @param userId
     * @param orderNo
     * @param quantity
     * @param pid
     * @param reward
     * @param type
     * @param rewardType
     */
    private void rewardShare(Long userId, String orderNo, Integer quantity, String reward, int type, Integer rewardType) {
        Boolean isReward = false;

        if (rewardType != null && rewardType == MallActRewardTypeEnum.yes.getIndex()) {
            isReward = true;
        }

        String[] rewards = reward.split("_");
        UserEntity userEntity = userDao.get(userId);
        String name = userEntity.getName();
        for (int i = 0; i < rewards.length; i++) {
            BigDecimal tem = new BigDecimal(rewards[i]);
            tem = tem.multiply(new BigDecimal(quantity));
            if (userEntity == null) break;
            accountService.reward(userEntity.getId(), type, tem, name, orderNo, isReward, AccountRecordBusEnum.SHARE_REWARD.getIndex());
            userEntity = userDao.get(userEntity.getPid());
        }
    }

    /**
     * 触发区域活动
     *
     * @param orderNo
     * @param quantity
     * @param rewardType
     * @param userId
     */
    private void fireAreaAct(String orderNo, String province, String city, String county, Integer quantity, Integer rewardType, Long userId, String reward) {
        Boolean isReward = false;
        if (rewardType == MallActRewardTypeEnum.yes.getIndex()) isReward = true;
        String[] addrs = new String[]{province, province + city, province + city + county};
        if (reward==null){
            return;
        }String[] rewards = reward.split("_");
        //对每个产品进行各级代理的转账
        for (int i = 0; i < addrs.length; i++) {
            if (reward.length()<=i){
                return;
            }
            BigDecimal tem = new BigDecimal(rewards[i]);
            tem = tem.multiply(new BigDecimal(quantity));
            AreaEntity areaEntity = areaDao.findByName(addrs[i]);
            if (areaEntity == null) {
                continue;
            }
            UserEntity userEntity = userDao.get(userId);
            if (areaEntity.getId() != null) {
                accountService.reward(areaEntity.getUserId(), AccountTypeEnum.CASH.getIndex(), tem, userEntity.getName(), orderNo, isReward, AccountRecordBusEnum.AREA_REWARD.getIndex());
            }
        }
    }


    // 触发升级活动
    private void fireLevelUpAct(Long userId) {
        UserEntity userEntity = userDao.get(userId);
        LevelEntity minLv = this.levelDao.findBase();
        LevelEntity levelEntity = levelDao.findByUserId(userId);
        //不是最低级别
        if (!levelEntity.getLv().equals(minLv.getLv())) {
            return;
        }
        // 万元大礼，一购买就自动成为代理
        userEntity.setLevelId(levelDao.findVipBase().getId());
        this.userDao.update(userEntity);
    }

    /**
     * 取消升级
     *
     * @param userId
     */
    private void cancelLevelUpAct(Long userId) {
        UserEntity userEntity = userDao.get(userId);
        LevelEntity minLv = this.levelDao.findBase();
        LevelEntity levelEntity = levelDao.findByUserId(userId);
        //最低级别 不做处理
        if (levelEntity.getLv().equals(minLv.getLv())) {
            return;
        }
        // 重制为最低级别
        userEntity.setLevelId(levelDao.findBase().getId());
        this.userDao.update(userEntity);
    }

    /**
     * 重置提货卡
     *
     * @param orderEntity
     */
    private void reviewCard(String code) {
        MallCardEntity mallCardEntity = mallCardDao.findByCode(code);
        mallCardEntity.setUserId(null);
        mallCardEntity.setUpdateTime(null);
        mallCardDao.updateAll(mallCardEntity);
    }

    /**
     * 扣减订单的XX券 xx数量
     *
     * @param accountType return 实际消耗的券
     */
    private BigDecimal cutTicket(String orderNo, Long userId, Integer accountType, BigDecimal amount) {
        AccountEntity accountEntity = accountService.findByUserIdAndType(userId, accountType);
        BigDecimal tc = amount;
        //不足时就是余额
        if (accountEntity.getAmount().compareTo(tc) < 0) {
            tc = accountEntity.getAmount();
        }
        //扣减优惠券
        accountService.pay(userId, accountType, tc, orderNo);
        return tc;
    }

    /**
     * Long
     * 从活动中获取产品所可以用券信息
     *
     * @param goodsId
     * @return
     */
    public TicketVo getTicketVo(Long goodsId) {
        MallActEntity mallActEntity = this.mallActDao.findByGoodsIdAndstatus(goodsId, MallActStatusEnum.OPEN.getIndex());
        TicketVo ticketVo = new TicketVo();
        if (mallActEntity == null) {
            ticketVo.setCoupon(new BigDecimal(0));
            ticketVo.setPoint(new BigDecimal(0));
            ticketVo.setVoucher(new BigDecimal(0));
            return ticketVo;
        }
        ticketVo.setCoupon(mallActEntity.getMaxCoupon());
        ticketVo.setPoint(mallActEntity.getPoint());
        ticketVo.setVoucher(mallActEntity.getMaxVoucher());
        if (null == mallActEntity.getPoint()) {
            ticketVo.setPoint(new BigDecimal(0));
        }
        if (null == mallActEntity.getMaxVoucher()) {
            ticketVo.setVoucher(new BigDecimal(0));
        }
        if (null == mallActEntity.getMaxCoupon()) {
            ticketVo.setCoupon(new BigDecimal(0));
        }
        return ticketVo;
    }


    /**
     * 外部方法实现
     **/

    @Override
    public MallActEntity findByGoodsIdAndstatus(Long goodsId, int status) {
        return mallActDao.findByGoodsIdAndstatus(goodsId, status);
    }

    @Override
    public void fire(MallOrderEntity orderEntity) {
        //没有支付
        if (orderEntity.getPayStatus() == null || orderEntity.getPayStatus().equals(MallOrderPayStatusEnum.NOT_PAID.getIndex())) {
            return;
        }
        //赠送经验值
        UserEntity userEntity = userDao.get(orderEntity.getUserId());
        accountService.rewardExp(orderEntity.getUserId(), orderEntity.getPrice(), orderEntity.getOrderNo(), userEntity.getName(), true);
        //其它活动
        Boolean hasLevelUpAct = false;
        List<OrderItemEntity> itemEntities = itemDao.findByOrderId(orderEntity.getId());
        for (OrderItemEntity itemEntity : itemEntities) {
            MallActEntity mallActEntity = mallActDao.findByGoodsIdAndstatus(itemEntity.getGoodsId(), MallActStatusEnum.OPEN.getIndex());
            // 活动不存在
            if (mallActEntity == null) {
                return;
            }
            //给予现金券
            if (mallActEntity.getCashReward() != null && !mallActEntity.getCashReward().equals("")) {
                rewardShare(orderEntity.getUserId(), orderEntity.getOrderNo(), itemEntity.getQuantity(), mallActEntity.getCashReward(), AccountTypeEnum.CASH.getIndex(), mallActEntity.getCashType());
            }
            //给予购物券
            if (mallActEntity.getVoucherReward() != null && !mallActEntity.getVoucherReward().equals("")) {
                rewardShare(orderEntity.getUserId(), orderEntity.getOrderNo(), itemEntity.getQuantity(), mallActEntity.getVoucherReward(), AccountTypeEnum.VOUCHER.getIndex(), mallActEntity.getVoucherType());
            }
            // 给予优惠券
            if (mallActEntity.getCouponReward() != null && !mallActEntity.getCouponReward().equals("")) {
                rewardShare(orderEntity.getUserId(), orderEntity.getOrderNo(), itemEntity.getQuantity(), mallActEntity.getCouponReward(), AccountTypeEnum.COUPON.getIndex(), mallActEntity.getCouponType());
            }
            // 给予积分
            if (mallActEntity.getPointReward() != null && !mallActEntity.getPointReward().equals("")) {
                rewardShare(orderEntity.getUserId(), orderEntity.getOrderNo(), itemEntity.getQuantity(), mallActEntity.getPointReward(), AccountTypeEnum.POINT.getIndex(), mallActEntity.getPointType());
            }

            // 给予区域
            if (mallActEntity.getAreaReward() != null && !mallActEntity.getAreaReward().equals("")) {
                fireAreaAct(orderEntity.getOrderNo(), orderEntity.getProvince(), orderEntity.getCity(), orderEntity.getCounty(), itemEntity.getQuantity(), mallActEntity.getAreaType(), orderEntity.getUserId(), mallActEntity.getAreaReward());
            }

            // 升级活动
            if (mallActEntity.getName().equals(Const.LEVEL_UP_ACT)) {
                hasLevelUpAct = true;
            }
        }
        ;
        // 有升级活动
        if (hasLevelUpAct) {
            fireLevelUpAct(orderEntity.getUserId());
        }
    }

    /**
     * 获取提货卡可抵扣价格
     *
     * @param orderEntity
     * @return
     */
    public BigDecimal getCardPrice(MallOrderEntity orderEntity) {
        if (!isMallCardAct(orderEntity)) {
            return BigDecimal.ZERO;
        }
        if (orderEntity.getRemark() == null || orderEntity.getRemark().equals("")) {
            return BigDecimal.ZERO;
        }
        //参加了提货卡活动
        MallCardEntity mallCardEntity = mallCardDao.findByCode(orderEntity.getRemark());
        //提货卡不存在  这里不需要判断是否已经使用 在提交订单的时候卡已经是已经用掉状态了
        if (mallCardEntity == null) {
            return BigDecimal.ZERO;
        }
        if (mallCardEntity.getPrice() == null) {
            mallCardEntity.setPrice(BigDecimal.ZERO);
        }
        //活动卡有效
        return mallCardEntity.getPrice();
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void useCard(MallOrderEntity orderEntity) {
        if (!isMallCardAct(orderEntity)) return;
        useCard(orderEntity.getRemark(), orderEntity.getUserId());
    }


    private Boolean isMallCardAct(MallOrderEntity orderEntity) {
        List<OrderItemEntity> items = itemDao.findByOrderId(orderEntity.getId());
        OrderItemEntity itemEntity = items.get(0);
        MallActEntity actEntity = findByGoodsIdAndstatus(itemEntity.getGoodsId(), MallActStatusEnum.OPEN.getIndex());
        //提货卡活动 使用掉提货卡
        if (actEntity == null || !actEntity.getName().equals(Const.MALL_CARD_ACT)) {
            return false;
        }
        return true;
    }

    /**
     * 使用提货卡
     */
    private void useCard(String code, Long userId) {
        MallCardEntity mallCardEntity = mallCardDao.findByCode(code);
        mallCardEntity.setUserId(userId);
        mallCardEntity.setUpdateTime(new Date());
        mallCardDao.update(mallCardEntity);
    }

    @Override
    public void useTicket(MallOrderEntity orderEntity) {
        //总积分
        BigDecimal totalPoint = new BigDecimal(0);
        //总优惠券
        BigDecimal totalCoupon = new BigDecimal(0);
        //总购物券
        BigDecimal totalVoucher = new BigDecimal(0);
        List<OrderItemEntity> itemEntities = itemDao.findByOrderId(orderEntity.getId());
        for (OrderItemEntity item : itemEntities) {
            TicketVo ticketVo = getTicketVo(item.getGoodsId());
            BigDecimal quantity = new BigDecimal(item.getQuantity());
            //累计总积分
            totalPoint = totalPoint.add(quantity.multiply(ticketVo.getPoint()));
            //累计总优惠券
            totalCoupon = totalCoupon.add(quantity.multiply(ticketVo.getCoupon()));
            //累计总购物券
            totalVoucher = totalVoucher.add(quantity.multiply(ticketVo.getVoucher()));
        }
        ;
        //扣减积分
        BigDecimal tem = cutTicket(orderEntity.getOrderNo(), orderEntity.getUserId(), AccountTypeEnum.POINT.getIndex(), totalPoint);
        orderEntity.setPoint(tem);
        //扣减优惠券
        tem = cutTicket(orderEntity.getOrderNo(), orderEntity.getUserId(), AccountTypeEnum.COUPON.getIndex(), totalCoupon);
        orderEntity.setCoupon(tem);
        //扣减购物券
        tem = cutTicket(orderEntity.getOrderNo(), orderEntity.getUserId(), AccountTypeEnum.VOUCHER.getIndex(), totalVoucher);
        orderEntity.setVoucher(tem);
    }

    @Override
    public void validateSend(ItemVo itemVo, Integer orderType, Long fromUserId, Long toUserId) {
        MallActEntity actEntity = findByGoodsIdAndstatus(itemVo.getGoodsId(), MallActStatusEnum.OPEN.getIndex());
        MallGoodsEntity goodsEntity = mallGoodsDao.get(itemVo.getGoodsId());
        if (actEntity == null) return;
        //与管理员的操作无需验证
        if (fromUserId.equals(Const.ADMIN_ID) || toUserId.equals(Const.ADMIN_ID)) {
            return;
        }
        //转货
        if (orderType == MallOrderOrderTypeEnum.TRANSFER.getIndex()) {
            //转货限制
            if (YesNoEnum.yes.getIndex() != actEntity.getTransfer() && MallOrderOrderTypeEnum.TRANSFER.getIndex() == orderType) {
                throw new RRException(goodsEntity.getName() + "禁止转货!");
            }
            //零售产品不可以转货
            if (MallGoodsSaleTypeEnum.AGENT.getIndex() != goodsEntity.getSaleType()) {
                throw new RRException(goodsEntity.getName() + "禁止转货!");
            }

        }
        //限制发货
        if (YesNoEnum.yes.getIndex() != actEntity.getDelivery() && orderType == MallOrderOrderTypeEnum.DELIVERY.getIndex()) {
            throw new RRException(goodsEntity.getName() + "禁止转货!");
        }
    }

    @Override
    public MallActEntity findByName(String name) {
        return mallActDao.findByName(name);
    }

    @Override
    public void validateCommit(Long userId, String remark, ItemVo itemVo, List<? extends ItemVo> itemVos, Integer orderType) {
        //存在活动查看活动存在的一些限制
        MallGoodsEntity goodsEntity = mallGoodsDao.get(itemVo.getGoodsId());
        MallActEntity actEntity = findByGoodsIdAndstatus(itemVo.getGoodsId(), MallActStatusEnum.OPEN.getIndex());
        if (actEntity == null) return;
        if (!actEntity.getOpen()) {
            throw new RRException("活动已结束!");
        }
        //判断积分是否足够  quequnlong
        if (actEntity.getPoint() != null && !actEntity.getPoint().equals(BigDecimal.ZERO)) {
            AccountEntity accountPoint = accountService.findByUserIdAndType(userId, AccountTypeEnum.POINT.getIndex()); //根据id和类别查询账户信息(积分)
            if (accountPoint.getAmount().compareTo(actEntity.getPoint()) == -1) {
                throw new RRException("积分不足,购买产品需要" + actEntity.getPoint() + "积分");
            }
        }
        //转货
        if (orderType == MallOrderOrderTypeEnum.TRANSFER.getIndex()) {
            //转货限制
            if (YesNoEnum.yes.getIndex() != actEntity.getTransfer() && MallOrderOrderTypeEnum.TRANSFER.getIndex() == orderType) {
                throw new RRException(goodsEntity.getName() + "禁止转货!");
            }
            //零售产品不可以转货
            if (MallGoodsSaleTypeEnum.AGENT.getIndex() != goodsEntity.getSaleType()) {
                throw new RRException(goodsEntity.getName() + "禁止转货!");
            }

        }
        //限制发货
        if (YesNoEnum.yes.getIndex() != actEntity.getDelivery() && orderType == MallOrderOrderTypeEnum.DELIVERY.getIndex()) {
            throw new RRException(goodsEntity.getName() + "禁止发货!");
        }
        //提货卡活动验证
        if (actEntity.getName().equals(Const.MALL_CARD_ACT)) {
            if (itemVos.size() > 1) {
                throw new RRException("请单独下单提货!");
            }
            if (itemVos.get(0).getQuantity() > 1) {
                throw new RRException("一次只能提一件!");
            }
            if (remark == null || remark.equals("")) {
                throw new RRException("请输入提货卡");
            }
            MallCardEntity mallCardEntity = mallCardDao.findByCode(remark.trim());
            if (mallCardEntity == null) {
                throw new RRException("提货卡无效");
            }
            if (mallCardEntity.getGoodsName() != null && !mallCardEntity.getGoodsName().contains(goodsEntity.getName())) {
                throw new RRException("此提货卡不能提该商品");
            }
            if (mallCardEntity.getUserId() != null) {
                throw new RRException("提货卡已被使用!");
            }
        }
        //级别限购
        if (actEntity.getLevel() != null) {
            LevelEntity level = levelDao.findByUserId(userId);
            if (actEntity.getLevel().contains(level.getName())) {
                throw new RRException("当前级别不可以购买!");
            }
        }
        //限购数量
        if (actEntity.getNumber() != null) {
            Date date = new Date();
            Integer number = mallActDao.sumUserBuyNumber(actEntity.getStart(), actEntity.getEnd(), itemVo.getGoodsId(), userId);
            if (number == null) number = 0;
            number += itemVo.getQuantity();
            if (number > actEntity.getNumber()) {
                throw new RRException(goodsEntity.getName() + "限购:" + actEntity.getNumber());
            }
        }
        //捆绑销售
        if (actEntity.getBindGoodsId() != null) {
            if (actEntity.getBindGoodsQuantity() != null) {
                Boolean bindPass = false;
                for (ItemVo item : itemVos) {
                    //有绑定商品且数量正确
                    if (item.getGoodsId().equals(actEntity.getBindGoodsId()) && item.getQuantity() >= itemVo.getQuantity() * actEntity.getBindGoodsQuantity()) {
                        bindPass = true;
                        break;
                    }
                }
                //如果不通过
                if (!bindPass) {
                    MallGoodsEntity goodsEntity1 = mallGoodsDao.get(actEntity.getBindGoodsId());
                    throw new RRException("购买" + itemVo.getQuantity() + "X" + goodsEntity.getName() + "需要购买" + goodsEntity1.getName() + "X" + itemVo.getQuantity() * actEntity.getBindGoodsQuantity() + "才能购买");
                }
            }
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancel(MallOrderEntity orderEntity) {
        //如果是提货卡活动 重制提货卡 不需要支付
        if (isMallCardAct(orderEntity)) {
            reviewCard(orderEntity.getRemark());
        }
        //没有支付的不管
        if (orderEntity.getPayStatus() == null || orderEntity.getPayStatus().equals(MallOrderPayStatusEnum.NOT_PAID.getIndex())) {
            return;
        }
        //判断是否有升级活动
        List<OrderItemEntity> itemEntities = itemDao.findByOrderId(orderEntity.getId());
        Boolean hasLevelUpAct = false;
        for (OrderItemEntity itemEntity : itemEntities) {
            MallActEntity mallActEntity = mallActDao.findByGoodsIdAndstatus(itemEntity.getGoodsId(), MallActStatusEnum.OPEN.getIndex());
            // 活动不存在
            if (mallActEntity == null) {
                return;
            }
            // 存在升级活动
            if (mallActEntity.getName().equals(Const.LEVEL_UP_ACT)) {
                hasLevelUpAct = true;
                break;
            }
        }
        ;
        // 取消升级
        if (hasLevelUpAct) {
            cancelLevelUpAct(orderEntity.getUserId());
        }
    }
}
